﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ChordCreator.Model;
using ChordCreator.Services.ConfigurationServices;

namespace ChordCreator.Services
{
    class ChordResolver
    {
        private Scale scale_;
        private ScaleNote[] scaleNotes_;

        public ChordResolver(Scale scale)
        {
            scale_ = scale;
            scaleNotes_ = scale_.GetConcreteScale();
        }

        public string FormOutput(List<ScaleNote> notes, out List<ChordScale> list)
        {
            list = new List<ChordScale>();
            StringBuilder builder = new StringBuilder();
            IEnumerable<int> chordDegrees = notes.Select(x => x.Degree);

            Dictionary<Note, List<ScaleNote>> dictionary = new Dictionary<Note, List<ScaleNote>>();
            for (int i = 0; i < scaleNotes_.Count(); i++)
            {
                List<ScaleNote> newChordNotes = GenerateChordFromTonic(i + 1, chordDegrees);
                list.Add(new ChordScale(newChordNotes.ToArray()));

                dictionary.Add(scaleNotes_[i].Note, newChordNotes);
            }
            for (int i = 0; i < chordDegrees.Count(); i++)
            {
                foreach (var key in dictionary.Keys)
                {
                    Note value = dictionary[key][i].Note;
                    builder.Append(CurrentConfiguration.Instance.GetNotePresentation(value));
                    builder.Append(',');
                }
                builder.Remove(builder.Length - 1, 1);
                builder.AppendLine();
            }
            return builder.ToString();
        }

        private List<ScaleNote> GenerateChordFromTonic(int startDegree, IEnumerable<int> chordForm)
        {
            // Let`s startDegree = T = 1
            // Chord Form 1 3 5
            // startDegree = 2
            // Chord is 2 4 6
            List<ScaleNote> result = new List<ScaleNote>();
            foreach (var chordPart in chordForm)
            {
                int newChordPart = chordPart - 1 + startDegree;
                if (newChordPart > scaleNotes_.Count())
                {
                    newChordPart -= scaleNotes_.Count();
                }
                result.Add(GetScaleNoteByDegree(newChordPart));
            }
            return result;
        }

        private ScaleNote GetScaleNoteByDegree(int degree)
        {
            return new ScaleNote(degree, scaleNotes_[degree - 1].Note);
        }
    }
}
